home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************/
- /* poly.c */
- /* */
- /* Read in polygons from and input file of format: */
- /* */
- /* Number objects <number-objects> */
- /* Object <object-id> (object-type) { */
- /* OWMatrix <matrix-id> { (matrix) } */
- /* prop <property-id> { E{ vec } p{ vec } Kd{ val } Ks{ val } */
- /* NumMeshes <number-of-meshes> */
- /* (possible-mesh) */
- /* */
- /* OWMatrix identifies an object to world matrix, */
- /* prop identifies an object property, E is the emittance, */
- /* p is the reflectance, Kd = diffuse component, and Ks the specular */
- /* */
- /* where: */
- /* object-type = mesh, cube, cone, cylinder, or sphere */
- /* matrix = { vec } { vec } { vec } { vec } */
- /* vec = val val val */
- /* val = floating point value */
- /* possible-mesh = if (object-type == mesh) { read-mesh-in-place } */
- /* else { mesh-read-from-file } */
- /* mesh = Mesh <mesh-id> <number-polygons> { */
- /* Patch vert<vertex#> <num-vertices> { vertices } */
- /* Patch norm<norm#> <num-normals> { normals } */
- /* vertices = { vec } { vec } ... */
- /* normals = { vec } { vec } ... */
- /* */
- /**********************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include "misc.h"
- #include "geo.h"
- #include "struct.h"
- #include "io.h"
- #include "poly.h"
- #include "rad.h"
- #include "adj.h"
- #include "bvol.h"
- #include "ff.h"
- #include "rtime.h"
-
- #define ENLARGE_BOX (0.000) /* Amount to enlarge obj BV by */
- #define ENLARGE_WORLD (0.6) /* Amount to enlarge world BV by */
-
- extern Time_Stats tstats;
- extern double MIN_ELEMENT_PERC;
- extern HBBox Scene_BVH;
- extern Vertex_list *vlist;
- extern unsigned long vlist_size;
- extern Vertex_tree *vtree;
- extern unsigned long vtree_size;
- extern FF_OptionType FF_Options;
- extern BoundingBoxType BoxCone();
- extern BoundingBoxType BoxCube();
- extern BoundingBoxType BoxCylinder();
- extern BoundingBoxType BoxSphere();
- extern void SetOptions();
- extern void LogStats();
- extern void LogRlog();
- extern void Create_Initial_ReceiverList();
-
- #ifdef IRIS4D
- extern void InitRad();
- extern void DoRad();
- extern void CleanUpRad();
- #endif /* IRIS4D */
-
- /**********************************************************************/
- /* Structures for reading scene */
- /**********************************************************************/
- char *tmp = " ";
- char *tmp2 = " ";
- float tmpf[9]; /* For floating pt reading only ! */
- int premesh = 0;
-
- RadParams ReadLog; /* Radiosity parameters */
- Scene RadScene; /* Scene to do radiosity on */
-
- /**********************************************************************/
- void Read_Prim_Mesh();
- void Read_Mesh();
- void Read_Polygon();
- void Read_MToW();
- void Read_Surface_Properties();
- void GetMeshFromFile();
- int Read_Objects();
- void Read_Scene();
- void Print_InitialStats();
-
- /*====================================================================*/
- /* Polygon setup routines */
- /*====================================================================*/
- /**********************************************************************/
- /* Get d paramater of plane for a polgyon */
- /**********************************************************************/
- double Poly_PlaneD(poly_normal, poly_point)
- Vector poly_normal, poly_point;
- {
- return(-dot(&poly_normal, &poly_point));
- }
-
- /**********************************************************************/
- /* Get area of a n-sided polygon using Stoke's Theorem */
- /**********************************************************************/
- double Poly_Area(v, norm, num_vert)
- Vector v[MAX_PATCH_VTX];
- Vector norm;
- int num_vert;
- {
- double area;
- Vector v_cross_v1;
- int i;
- double sum_v;
-
- sum_v = 0.0;
- for (i=0;i<num_vert;i++) {
- v_cross_v1 = cross(&v[i],&v[(i+1) % num_vert]);
- sum_v += dot(&norm, &v_cross_v1);
- }
- area = 0.5 * _ABS(sum_v);
- if (area <= DAMN_SMALL)
- printf("Hey the area is really small.\n");
- if (area == 0.0) {
- printf("Hey the area is too small.\n");
- exit(1);
- }
- return area;
- }
-
- /**********************************************************************/
- /* Find U, V, W planes formed by edges of quad or triangle */
- /**********************************************************************/
- void Poly_UVW(pptr)
- Polygon *pptr;
- {
- int i;
- Vector u,v,w;
- Vector corner[MAX_PATCH_VTX];
- polyUVW *uvw;
-
- uvw = (polyUVW *) malloc(sizeof(polyUVW));
-
- for (i=0;i<pptr->numVert;i++)
- corner[i] = pptr->vert[i]->pos;
-
- if (pptr->class == PATCH) {
- u = *vsub(&corner[1], &corner[0]);
- uvw->Lu = vlen(&u);
- norm(&u);
- uvw->Nu = cross(&pptr->normal[0], &u);
- uvw->du = Poly_PlaneD(uvw->Nu, corner[1]);
-
- v = *vsub(&corner[3], &corner[0]);
- uvw->Lv = vlen(&v);
- norm(&v);
- uvw->Nv = cross(&v, &pptr->normal[0]);
- uvw->dv = Poly_PlaneD(uvw->Nv, corner[3]);
-
- } else if (pptr->class == TRIANGLE) {
- u = *vsub(&corner[1], &corner[0]);
- uvw->Lu = vlen(&u);
- norm(&u);
- uvw->Nu = cross(&pptr->normal[0], &u);
- uvw->du = Poly_PlaneD(uvw->Nu, corner[1]);
-
- v = *vsub(&corner[2], &corner[1]);
- uvw->Lv = vlen(&v);
- norm(&v);
- uvw->Nv = cross(&pptr->normal[0], &v);
- uvw->dv = Poly_PlaneD(uvw->Nv, corner[2]);
-
- w = *vsub(&corner[0], &corner[2]);
- uvw->Lw = vlen(&w);
- norm(&w);
- uvw->Nw = cross(&pptr->normal[0], &w);
- uvw->dw = Poly_PlaneD(uvw->Nw, corner[0]);
-
- } else {
- fprintf(stderr, "Polygon type not supported. Can't calculate UVW.\n");
- exit(1);
- }
- pptr->uvw = uvw;
- }
-
-
- /*====================================================================*/
- /* Scene reading routines */
- /*====================================================================*/
-
- /**********************************************************************/
- /* Initialize size of world */
- /**********************************************************************/
- void Init_WorldSize(rlog)
- RadParams *rlog;
- {
- rlog->worldbox.min.x = VERY_LARGE / 2.0;
- rlog->worldbox.min.y = VERY_LARGE / 2.0;
- rlog->worldbox.min.z = VERY_LARGE / 2.0;
- rlog->worldbox.max.x = -VERY_LARGE / 2.0;
- rlog->worldbox.max.y = -VERY_LARGE / 2.0;
- rlog->worldbox.max.z = -VERY_LARGE / 2.0;
- rlog->worldSize = VERY_LARGE / 2.0;
- }
-
- /**********************************************************************/
- /* Find minumum bounding box size for the world */
- /**********************************************************************/
- void Update_WorldSize(pt)
- Vector pt;
- {
- if (pt.x > ReadLog.worldbox.max.x) ReadLog.worldbox.max.x = pt.x;
- if (pt.y > ReadLog.worldbox.max.y) ReadLog.worldbox.max.y = pt.y;
- if (pt.z > ReadLog.worldbox.max.z) ReadLog.worldbox.max.z = pt.z;
-
- if (pt.x < ReadLog.worldbox.min.x) ReadLog.worldbox.min.x = pt.x;
- if (pt.y < ReadLog.worldbox.min.y) ReadLog.worldbox.min.y = pt.y;
- if (pt.z < ReadLog.worldbox.min.z) ReadLog.worldbox.min.z = pt.z;
- }
-
- /**********************************************************************/
- /* Make bounding sphere and bounding box of world */
- /**********************************************************************/
- void BoxWorld(rlog)
- RadParams *rlog;
- {
- if (rlog->worldbox.min.x > rlog->worldbox.max.x) {
- printf("Oh oh. the world min is greater than the max!\n");
- exit(1);
- }
- rlog->worldbox.min.x -= ENLARGE_WORLD;
- rlog->worldbox.min.y -= ENLARGE_WORLD;
- rlog->worldbox.min.z -= ENLARGE_WORLD;
- rlog->worldbox.max.x += ENLARGE_WORLD;
- rlog->worldbox.max.y += ENLARGE_WORLD;
- rlog->worldbox.max.z += ENLARGE_WORLD;
-
- rlog->worldSize = 0.5 * (vdist(&(rlog->worldbox.max),
- &(rlog->worldbox.min)) + 0.5);
- }
-
- /**********************************************************************/
- /* Make bounding sphere and bounding box of world */
- /**********************************************************************/
- void Enlarge_BoxSize(box)
- BoundingBoxType *box;
- {
- box->min.x -= ENLARGE_BOX;
- box->min.y -= ENLARGE_BOX;
- box->min.z -= ENLARGE_BOX;
- box->max.x += ENLARGE_BOX;
- box->max.y += ENLARGE_BOX;
- box->max.z += ENLARGE_BOX;
- }
-
- /**********************************************************************/
- /**********************************************************************/
- void Presub_Polygon(pptr, level)
- Polygon *pptr;
- int level;
- {
- int i;
-
- /* printf("At level %d\n", level); */
- if (level <= 0) return;
- else {
- Subdivide_Polygon(pptr);
- level--;
- for (i=0;i<MAX_PATCH_CHILDREN;i++)
- Presub_Polygon(pptr->child[i], level);
- }
- }
-
- /**********************************************************************/
- /* Read in polygon info */
- /**********************************************************************/
- void Read_Polygon(meshf, pptr, mptr, optr, origB)
- FILE *meshf;
- Polygon *pptr;
- Mesh *mptr;
- Objectt *optr;
- Spectra origB;
- {
- int i,j;
- float tmpf[4];
- char *tmp = " ";
- Vector va[MAX_PATCH_VTX];
- Vector v;
-
- /* Read in name and number of normals for the patch */
- fscanf(meshf,"%s %d {",tmp , &(pptr->numVert));
- pptr->id = ReadLog.totpoly++;
- pptr->next = pptr+1;
- if (Option.debug) printf(" Patch %s %d {", tmp, pptr->numVert);
-
- /* Set id, type, no children, tree level, mesh poly belongs to,
- and poly, this poly belongs to */
- if (pptr->numVert == 4) {
- pptr->name = PATCH_ID;
- pptr->class = PATCH;
- } else if (pptr->numVert == 3) {
- pptr->name = TRI_ID;
- pptr->class = TRIANGLE;
- } else {
- fprintf(stderr, "Sorry, only quadtralaterals and triangles allowed\n");
- exit(1);
- }
- for(i=0;i<MAX_PATCH_CHILDREN;i++)
- pptr->child[i] = 0; /* No children yet */
- pptr->level = 0; pptr->Pfather = 0; /* is root of quad-tri tree */
- pptr->Mfather = mptr; /* mesh poly belongs to */
- pptr->Links = (PolyList *)0; /* No form factor links */
- pptr->polyhead.front = pptr->polyhead.back = pptr->Links;
- pptr->polyhead.num_polys = 0;
-
- /* Set total and unshot radiosity values for patch, and vertices */
- for(i=0;i<MAX_SPECTRA_SAMPLES;i++) {
- pptr->unshot_B.samples[i] = pptr->B.samples[i] = origB.samples[i];
- for (j=0;j<pptr->numVert;j++)
- pptr->vtx_B[j].samples[i] = origB.samples[i];
- }
-
- /* Read normals of patch */
- for (i=0;i<(pptr->numVert);i++) {
- fscanf(meshf, " { %g %g %g }", &tmpf[0], &tmpf[1], &tmpf[2]);
- pptr->normal[i].x = tmpf[0];
- pptr->normal[i].y = tmpf[1];
- pptr->normal[i].z = tmpf[2];
- norm(&(pptr->normal[i]));
-
- /* Rotate normals if needed into world space */
- if (same_matrix3x3(optr->MToW, Identity) == 0) {
- pptr->normal[i] = vrotate(pptr->normal[i], optr->MToW);
- norm(&(pptr->normal[i]));
- }
-
- if (Option.debug)
- printf(" { %g %g %g }", (pptr->normal[i].x),
- (pptr->normal[i].y),(pptr->normal[i].z));
- }
- fscanf(meshf," }\n"); /* End normal read */
- if (Option.debug) printf(" }\n");
-
- /* Read in size = number of vertices of patch */
- fscanf(meshf, "Patch %s %d {", tmp, &(pptr->numVert));
- if (Option.debug) printf(" Patch %s %d {", tmp, pptr->numVert);
-
- /* Read vertices of patch */
- for (i=0;i<(pptr->numVert);i++) {
- fscanf(meshf, " { %g %g %g }", &tmpf[0], &tmpf[1], &tmpf[2]);
- v.x = tmpf[0];
- v.y = tmpf[1];
- v.z = tmpf[2];
-
- /* Transform vertex if needed into world space */
- if (same_matrix(optr->MToW, Identity) == 0)
- v = vtransform(v, optr->MToW);
- if (Option.debug) printf(" {%g %g %g}", v.x, v.y, v.z);
- va[i] = v;
-
- /* Update size of the world, and size of bounding box for mesh */
- Update_WorldSize(v);
- if (optr->num_meshes != -1) /* Is not a primitive */
- Update_BoxSize(v,optr->box);
- if (optr->primid == MESH)
- Update_BoxSize(v,mptr->box);
-
- /* Form adjacency links between vertices and polygon */
- if (vtree == 0) { /* Empty vertex tree */
- pptr->vert[i] = Vertex_Create(v,pptr);
- vtree = VTree_NodeCreate(pptr->vert[i],0); /* No father, is root */
- } else {
- VTree_NodeFind(v,vtree,pptr,i);
- }
-
- }
- fscanf(meshf," }\n"); /* End polygon vertex read */
- if (Option.debug) printf(" }\n");
-
- /* Calculate area and d of plane where poly resides */
- pptr->d = Poly_PlaneD(pptr->normal[1], va[1]);
- pptr->area = Poly_Area(va, pptr->normal[0], pptr->numVert);
-
- /* Calculate u,v,w planes of edges of poly */
- Poly_UVW(pptr);
- pptr->changingNormal = 0;
-
- /* Calculate total energy and total area in scene */
- ReadLog.totalArea += pptr->area;
- for(i=0;i<MAX_SPECTRA_SAMPLES;i++)
- ReadLog.totalEnergy += origB.samples[i] * pptr->area;
-
- /* Pre-subdivide if specified */
- if (premesh == 1)
- Subdivide_Polygon(pptr);
- else if (premesh > 1)
- Presub_Polygon(pptr, premesh);
- }
-
- /**********************************************************************/
- /* Read mesh info */
- /**********************************************************************/
- void Read_Mesh(meshf, optr)
- FILE *meshf;
- Objectt *optr;
- {
- Mesh *mptr;
- Polygon *pptr;
- char *tmp = " ";
-
- if (Option.debug) printf(" NumMeshes %d\n", optr->num_meshes);
- mptr = optr->meshes
- = (Mesh *)malloc ((optr->num_meshes) *sizeof(Mesh));
- ReadLog.meshcount = 0;
-
- /* Read in mesh information from current input file */
- while ((fscanf(meshf," Mesh ") != -1) &&
- (ReadLog.meshcount < optr->num_meshes)) {
-
- /* Allocate space for polygons in mesh */
- fscanf(meshf, "%s %d {\n", tmp, &(mptr->num_polys));
- mptr->id = ReadLog.totmesh++;
- mptr->name = MESH_ID;
- mptr->Ofather = optr;
- pptr = mptr->polys
- = (Polygon *)malloc ((mptr->num_polys) *sizeof(Polygon));
-
- /* Allocate space for mesh bounding box if object is
- a polygonal mesh */
- if (optr->primid == MESH) {
- mptr->box = (BoundingBoxType *) malloc(sizeof(BoundingBoxType));
- BoxInit(mptr->box);
- } else
- mptr->box = (BoundingBoxType *)0;
-
- if (Option.debug) printf(" Mesh %s %d {\n", tmp, mptr->num_polys);
-
- /* Read in polygon information for mesh */
- ReadLog.polycount = 0;
- while ((fscanf(meshf," Patch ") != -1) &&
- (ReadLog.polycount < mptr->num_polys)) {
-
- Read_Polygon(meshf,pptr,mptr,optr,optr->surface->rad.E);
- pptr++;
- ReadLog.polycount++;
- }
- fscanf(meshf," }\n"); /* End mesh read */
-
- mptr++;
- ReadLog.meshcount++;
- }
- }
-
- /**********************************************************************/
- /* Read object to world space matrix, and create inverse matrix */
- /**********************************************************************/
- void Read_MToW(meshf, optr)
- FILE *meshf;
- Objectt *optr;
- {
- int i,j;
-
- /* Read in object to world matrix, and set world-object matrix */
- fscanf(meshf,"OWMatrix %s { ", tmp);
- copy_matrix(Identity, optr->MToW);
- for (i=0; i<4; i++) for (j=0; j<3; j++) {
- fscanf(meshf,"%g ", &tmpf[0]);
- optr->MToW[i][j] = tmpf[0];
- }
- invert_matrix(optr->MToW,optr->WToM);
- fscanf(meshf,"}\n"); /* End read matrix */
-
- if (Option.debug) {
- printf(" OWMatrix %s {\n", tmp);
- for(i=0;i<4;i++) {
- printf("\t");
- for(j=0;j<4;j++) printf("%g ", optr->MToW[i][j]);
- printf("\n");
- }
- }
- }
-
- /**********************************************************************/
- /* Allocate space and read in object surface properties */
- /**********************************************************************/
- void Read_Surface_Properties(meshf, optr)
- FILE *meshf;
- Objectt *optr;
- {
- SurfaceProp *sptr;
- static int surfprop_id = 0;
-
- /* Allocate space for surface properties */
- sptr = optr->surface = (SurfaceProp *)malloc(sizeof(SurfaceProp));
-
- fscanf(meshf,
- " Prop %s { E{ %g %g %g } p{ %g %g %g } Kd{ %g } Ks{ %g } }\n",
- tmp, &tmpf[0], &tmpf[1], &tmpf[2], &tmpf[3], &tmpf[4], &tmpf[5],
- &tmpf[6], &tmpf[7]);
- sptr->id = surfprop_id++;
- sptr->name = tmp;
- sptr->rad.E.samples[0] = tmpf[0]; /* Emittance */
- sptr->rad.E.samples[1] = tmpf[1];
- sptr->rad.E.samples[2] = tmpf[2];
- sptr->shade.p.samples[0] = tmpf[3]; /* Reflectance */
- sptr->shade.p.samples[1] = tmpf[4];
- sptr->shade.p.samples[2] = tmpf[5];
- sptr->shade.Kd.samples[0] = tmpf[6]; /* Diffuse & specular coefficients */
- sptr->shade.Ks.samples[0] = tmpf[7];
- sptr->rad.B.samples[0] = 0.0; /* Radiance */
- sptr->rad.B.samples[1] = 0.0;
- sptr->rad.B.samples[2] = 0.0;
-
- if (Option.debug)
- printf(" Prop %s { E{ %g %g %g } p{ %g %g %g } Kd{ %g } Ks{ %g } }\n",
- tmp, sptr->rad.E.samples[0],
- sptr->rad.E.samples[1], sptr->rad.E.samples[2],
- sptr->shade.p.samples[0], sptr->shade.p.samples[1],
- sptr->shade.p.samples[2],
- sptr->shade.Kd.samples[0], sptr->shade.Ks.samples[0]);
- }
-
- /**********************************************************************/
- /* Read in mesh from primitive mesh file */
- /**********************************************************************/
- void Read_Prim_Mesh(filename, optr)
- char *filename;
- Objectt *optr;
- {
- if (!(pmesh = fopen(filename, "r"))) {
- fprintf(stderr,"%s: cannot read object file %s\n", ProgName, filename);
- exit(1);
- }
-
- fscanf(pmesh, "NumMeshes %d\n", &(optr->num_meshes));
- ReadLog.polycount = 0;
- Read_Mesh(pmesh, optr);
- fclose(pmesh);
- }
-
- /**********************************************************************/
- /* Read in scene from a input file */
- /**********************************************************************/
- void GetMeshFromFile(objtype, optr)
- char *objtype;
- Objectt *optr;
- {
- BoundingBoxType obox;
-
- optr->primtype = objtype;
-
- /* Check if normals facing in or out */
- if (optr->num_meshes == -2)
- optr->in_facingprim = TRUE;
- else
- optr->in_facingprim = FALSE;
-
- if (strcmp(objtype,"cone") == 0) {
- obox = BoxCone();
- optr->primid = CONE;
- if (optr->num_meshes == -2) {
- if (ReadLog.log) printf("\t*** cone(in) reading...\n");
- Read_Prim_Mesh(iconefilename, optr);
- } else {
- if (ReadLog.log) printf("\t*** cone(out) reading...\n");
- Read_Prim_Mesh(conefilename, optr);
- }
- } else if (strcmp(objtype,"cube") == 0) {
- obox = BoxCube();
- optr->primid = CUBE;
- if (optr->num_meshes == -2) {
- if (ReadLog.log) printf("\t*** cube(in) reading...\n");
- Read_Prim_Mesh(icubefilename, optr);
- } else {
- if (ReadLog.log) printf("\t*** cube(out) reading...\n");
- Read_Prim_Mesh(cubefilename, optr);
- }
- } else if (strcmp(objtype,"cylinder") == 0) {
- obox = BoxCylinder();
- optr->primid = CYLINDER;
- if (optr->num_meshes == -2) {
- if (ReadLog.log) printf("\t*** cylinder(in) reading...\n");
- Read_Prim_Mesh(icylfilename, optr);
- } else {
- if (ReadLog.log) printf("\t*** cylinder(out) reading...\n");
- Read_Prim_Mesh(cylfilename, optr);
- }
- } else if (strcmp(objtype,"sphere") == 0) {
- obox = BoxSphere();
- optr->primid = SPHERE;
- if (optr->num_meshes == -2) {
- if (ReadLog.log) printf("\t*** sphere(in) reading...\n");
- Read_Prim_Mesh(isphfilename, optr);
- } else {
- if (ReadLog.log) printf("\t*** sphere(out) reading...\n");
- Read_Prim_Mesh(sphfilename, optr);
- }
- } else {
- printf("There's something wrong, primitive is invalid\n");
- exit(0);
- }
- /* optr->num_meshes = -1; */
-
- /* Get transformed bounding box for object if tranformation
- not Identity */
- if (same_matrix3x3(optr->MToW, Identity) == 0)
- Bounds_Transform(optr->MToW, obox, optr->box);
- Option.debug = 0;
- }
-
- char *objmatch[5] =
- {
- "precone", "precube", "precylinder", "premesh", "presphere"
- };
- char *objreal[5] =
- {
- "cone", "cube", "cylinder", "mesh", "sphere"
- };
- /**********************************************************************/
- /* Search string a for b, and return first number found */
- /**********************************************************************/
- int Check_premesh(a, realtype)
- char *a, **realtype;
- {
- int match = 0; /* Match found */
- char level[2]; /* level to subdivide to */
- int i;
-
- i=0;
- while (i<5 && !match) /* Scan for object type, return type */
- if (strstr(a,objmatch[i])) {
- match = 1;
- *realtype = objreal[i];
- }
- else i++;
-
- if (match) /* Scan for number of levels to mesh to */
- for (i=0;i<9;i++) {
- sprintf(level, "%d", i+1);
- if (strstr(a, level))
- match = i+1;
- }
- return(match);
- }
-
- /**********************************************************************/
- /* Read in objects from file */
- /**********************************************************************/
- int Read_Objects(filename, obj)
- char *filename;
- Objectt **obj;
- {
- int nobjs = 0; /* Number of objects to read */
- Objectt *optr;
-
- if (!(meshf = fopen(filename, "r"))) {
- fprintf(stderr,"%s: cannot read object file %s\n", ProgName, filename);
- exit(1);
- }
-
- /* Find out # of objects and allocate space */
- fscanf(meshf,"Number objects %d\n", &nobjs);
- if (Option.debug) printf("Number objects %d\n", nobjs);
- optr = *obj = (Objectt *)malloc (nobjs *sizeof(Objectt));
-
- /* Scan for objects (id, object type) */
- ReadLog.objcount = 0;
- while ((fscanf(meshf,"Object") != -1) && (ReadLog.objcount < nobjs)) {
-
- /* Set id, name, and primitive type */
- fscanf(meshf, "%s %s {\n", tmp, tmp2);
- optr->id = ReadLog.objcount;
- optr->rayID = -1;
- optr->name = "object";
- optr->primtype = tmp2;
-
- if (premesh = Check_premesh(tmp2,&optr->primtype))
- printf("\t Tesselating %s (%d) to level %d\n",
- optr->primtype, optr->id, premesh);
-
- if (Option.debug)
- printf("Object%d %s %s {\n", optr->id, optr->name, optr->primtype);
-
- /* Allocate space for object bounding volume */
- optr->box = (BoundingBoxType *) malloc(sizeof(BoundingBoxType));
-
- /* Read model to world matrix */
- Read_MToW(meshf, optr);
-
- /* Read surface properties */
- Read_Surface_Properties(meshf, optr);
-
- /* Find out number of meshes in object */
- fscanf(meshf, " NumMeshes %d\n", &(optr->num_meshes));
-
- if ((optr->num_meshes) == -1 || (optr->num_meshes) == -2) {
- /* Read in mesh info from primitive-mesh input files */
- /* depending on type of object */
- GetMeshFromFile(optr->primtype,optr);
-
- } else {
- /* Reading in mesh info from current input file */
- if (ReadLog.log) printf("\t*** mesh reading...\n");
- optr->primid = MESH;
- BoxInit(optr->box);
- Read_Mesh(meshf, optr);
- }
- fscanf(meshf,"}\n"); /* End object read */
- if (Option.debug) printf("}\n");
-
- /* Enlarge box around object just a bit ? */
- /* Enlarge_BoxSize(optr->box); */
-
- optr++;
- ReadLog.objcount++;
- }
-
- ReadLog.totalEnergyLeft = ReadLog.totalEnergy;
- fclose(meshf);
- return(ReadLog.objcount);
- }
-
- /**********************************************************************/
- /* Read in textures from file */
- /**********************************************************************/
- int Read_Textures(filename, tex)
- char *filename;
- TextureProp **tex;
- {
- if (!(textf = fopen(filename, "r"))) {
- fprintf(stderr,"%s: cannot read texture file %s\n", ProgName, filename);
- exit(1);
- }
- printf("Not implemented yet...sorry no textures\n");
- return 0;
- }
-
- /**********************************************************************/
- /* Print element / receiver list */
- /**********************************************************************/
- void Print_Elements(elist,elist_size)
- Elist *elist;
- int elist_size;
- {
- int i;
- Elist *elptr;
-
- elptr = elist;
- for(i=0;i<elist_size;i++,elptr=elptr->next)
- printf("\tElement %s%d, ff %g, is %sa receiver\n",
- elptr->element->name, elptr->element->id,
- elptr->ff, (elptr->is_receiver == 1 ? "" : "not "));
- }
-
- /**********************************************************************/
- /* Print program options, and statistics */
- /**********************************************************************/
- void Print_InitialStats(rlog,fp)
- RadParams rlog;
- FILE *fp;
- {
- if (rlog.log) {
- fprintf(fp,"\n\t*** Scene statistics ***\n");
- fprintf(fp,"\tTotal objects read: %d\n", rlog.objcount);
- fprintf(fp,"\tTotal meshes read: %d\n", rlog.totmesh);
- fprintf(fp,"\tTotal polygons read: %d\n", rlog.totpoly);
- fprintf(fp,"\tTotal vertices read to octree: %d\n", vtree_size);
- fprintf(fp,"\tTotal textures read: %d\n", rlog.num_textures);
- fprintf(fp,"\n");
- /* if (ReadLog.num_elements > 0) {
- fprintf(fp,"\tTotal elements read: %d\n", rlog.num_elements);
- Print_Elements(rlog.elements, rlog.num_elements);
- fprintf(fp,"\tTotal receivers: %d\n", rlog.num_receivers);
- } */
- fprintf(fp,"\tStopping threshold: %g and iterations: %d\n", rlog.threshold,
- rlog.max_iterations);
- fprintf(fp,"\tIntensity scale for display: %g\n", rlog.intensityScale);
- /* if (Option.ambient)
- fprintf(fp,"\tInitial ambient term: (%g %g %g)\n",
- rlog.ambient_term.samples[0], rlog.ambient_term.samples[1],
- rlog.ambient_term.samples[2]);
- */
- fprintf(fp,"\tThe worlds radius is: %g\n", rlog.worldSize);
- fprintf(fp,"\t\twith min-point %g,%g,%g\n\t\tand max-point %g,%g,%g\n",
- rlog.worldbox.min.x, rlog.worldbox.min.y, rlog.worldbox.min.z,
- rlog.worldbox.max.x, rlog.worldbox.max.y, rlog.worldbox.max.z);
- fprintf(fp,"\t\thas a total energy of: %g\n", rlog.totalEnergy);
- fprintf(fp,"\t\tand has a total area of: %g\n", rlog.totalArea);
-
- ff_print_FF_Options(FF_Options);
- if (Option.ff_raytrace == 0) {
- fprintf(fp,"\tUsing hemicube visibility testing, with\n");
- fprintf(fp,"\ttop resolution of %d\n", rlog.hemicubeRes);
- } else {
- if (FF_Options.quadtri_ray)
- fprintf(fp,"\tUsing Ray-QuadTri intersection test.\n");
- else
- fprintf(fp,"\tUsing Ray-General Polygon intersection test.\n");
- if (Option.grid)
- fprintf(fp,"\tUsing hierarchical bounding volumes\n");
- if (FF_Options.shaft_cull)
- fprintf(fp,"\tUsing source/receiver shaft culling\n");
- else {
- if (FF_Options.src_rec_cull)
- fprintf(fp,"\tUsing source and receiver plane culling.\n");
- else
- fprintf(fp,"\tUsing source plane culling.\n");
- }
- }
- fprintf(fp,"\n");
- }
- }
-
- /**********************************************************************/
- /* Read in the scene (s) from file */
- /**********************************************************************/
- void Read_Scene(s)
- Scene *s;
- {
- printf("\n\t*** Reading scene from %s ***\n",Option.meshfilename);
-
- /* Initialize size of the world */
- Init_WorldSize(&ReadLog);
-
- /* Create vertex octree */
- /* vtree = VTree_Create(ReadLog); */
-
- /* Read in objects and textures */
- s->num_objects = Read_Objects(Option.meshfilename, &(s->objects));
- /* s->num_textures = Read_Textures(Option.textfilename, &(s->textures)); */
-
- /* Read in PR view */
- printf("\n\t*** Reading view from %s ***\n", Option.viewfilename);
- Read_View(Option.viewfilename,&(ReadLog.displayView));
-
- /* Calculate minimum world size */
- BoxWorld(&ReadLog);
-
- /* Set minimum element area */
- FF_Options.min_element_area = (MIN_ELEMENT_PERC * ReadLog.totalArea /
- (double) ReadLog.totpoly);
- }
-
- /**********************************************************************/
- /* Read in a view */
- /**********************************************************************/
- void Read_View(filename,c)
- char *filename;
- Camera *c;
- {
- float t[3];
- int t1, t2;
-
- if (!(viewf = fopen(filename, "r"))) {
- fprintf(stderr,"\t%s: cannot read view file %s\n", ProgName, filename);
- fprintf(stderr,"\tSetting to default viewing parameters\n");
- c->lookfrom.x = ReadLog.worldbox.max.x - 2.*ENLARGE_WORLD;
- c->lookfrom.y = ReadLog.worldbox.max.y - 2.*ENLARGE_WORLD;
- c->lookfrom.z = ReadLog.worldbox.max.z - 2.*ENLARGE_WORLD;
- c->lookat.x = (ReadLog.worldbox.max.x - ReadLog.worldbox.min.x ) / 2.0;
- c->lookat.y = (ReadLog.worldbox.max.y - ReadLog.worldbox.min.y ) / 2.0;
- c->lookat.z = (ReadLog.worldbox.max.z - ReadLog.worldbox.min.z ) / 2.0;
- c->lookup.x = 0.; c->lookup.y = 1.; c->lookup.z = 0.;
- c->fovx = 60; c->fovy = 60;
- c->near = 0.001; c->far = ReadLog.worldSize;
- c->xRes = 256; c->yRes = 256;
- c->bank = 0.0;
-
- } else {
- fscanf(viewf,"Camera {\n");
-
- fscanf(viewf,"lookfrom %g %g %g\n", &t[0], &t[1], &t[2]);
- c->lookfrom.x = t[0];
- c->lookfrom.y = t[1];
- c->lookfrom.z = t[2];
-
- fscanf(viewf,"lookat %g %g %g\n", &t[0], &t[1], &t[2]);
- c->lookat.x = t[0];
- c->lookat.y = t[1];
- c->lookat.z = t[2];
-
- fscanf(viewf,"lookup %g %g %g\n", &t[0], &t[1], &t[2]);
- c->lookup.x = t[0];
- c->lookup.y = t[1];
- c->lookup.z = t[2];
-
- fscanf(viewf,"fovx %d fovy %d near %g far %g\n", &t1, &t2, &t[0], &t[1]);
- c->fovx = t1; c->fovy = t2;
- c->near = t[0]; c->far = t[1];
- fscanf(viewf,"xRes %d yRes %d\n", &t1, &t2);
- c->xRes = t1; c->yRes = t2;
- fscanf(viewf,"bank %g\n", &t[0]);
- c->bank = t[0];
- fscanf(viewf,"}");
- }
-
- /* Allocate buffer for display purposes */
- c->buffer = (unsigned long *)
- malloc(ReadLog.displayView.xRes * ReadLog.displayView.yRes *
- sizeof(unsigned long));
- }
-
- extern int p_count;
- /**********************************************************************/
- /* Main program... */
- /**********************************************************************/
- void main(argc, argv)
- int argc;
- char *argv[];
- {
- int temp;
- float prep_start, prep_end;
- float tot_start, tot_end;
- char *env_var = " ";
-
- /* Set up options */
- SetOptions(argc, argv);
- Init_Time();
-
- /* Open table log */
- if ((env_var = getenv("PR_run")) != NULL) {
- Option.tablelogstr = env_var;
- Option.tablelog = TRUE;
- LogRlog(1,Option.meshfilename,Option.tablelogstr);
- } else
- Option.tablelog = FALSE;
-
- /* Read the scene in */
- temp = Option.debug; Option.debug = 0;
-
- if (Option.statistics)
- prep_start = Cpu_Time(&tstats.utime, &tstats.stime);
-
- Read_Scene(&RadScene);
-
- if (Option.statistics) {
- prep_end = Cpu_Time(&tstats.utime, &tstats.stime);
- tstats.prep_Model = (prep_end - prep_start);
- }
-
- if (Option.statistics)
- if (Option.device == PRINT) Print_InitialStats(ReadLog,stdout);
- else Print_InitialStats(ReadLog,Option.StatFile);
- if (Option.print_scene) print_Scene(&RadScene,Option.InLogFilename);
- Option.debug = temp;
-
- /* Build hierarchical bounding volume tree for scene */
- if (Option.grid) {
-
- /* Build object HBV */
- prep_start = Cpu_Time(&tstats.utime, &tstats.stime);
-
- BVH_Create_Hierarchy(&RadScene, &Scene_BVH);
-
- prep_end = Cpu_Time(&tstats.utime, &tstats.stime);
- tstats.prep_oHBV = (prep_end - prep_start);
- tstats.tot_time += tstats.prep_oHBV;
-
- prep_start = Cpu_Time(&tstats.utime, &tstats.stime);
-
- /* Build polygon HBV */
- BVH_Create_PHierarchy(&Scene_BVH);
- /* printf("\t%d Polygons added to tree.\n", p_count); */
- Enlarge_Root();
-
- prep_end = Cpu_Time(&tstats.utime, &tstats.stime);
- tstats.prep_pHBV = (prep_end - prep_start);
- tstats.tot_time += tstats.prep_pHBV;
-
- if (Option.debug) {
- printf("\t*** Hierarchical BV tree ***\n");
- temp = Option.debug;
- Option.debug = 0;
- BVH_PrintBox(&Scene_BVH);
- BVH_PrintHier(&Scene_BVH);
- printf("\n");
- Option.debug = temp;
- }
- }
-
- /* Run radiosity on the scene */
- Init_Rad(&RadScene);
- Do_Rad();
-
- /* Perform cleanup */
- /* CleanUp_Rad(); */
- if (Option.statistics)
- if (Option.device == FILES)
- LogStats(0);
-
- /* Log scene with radiosity calculated */
- if (Option.print_scene) print_Scene(&RadScene, Option.OutLogFilename);
-
- /* Output polygonal scene to file */
- if (Option.write_result) {
- /* Create_Initial_ReceiverList(&RadScene); */
- Write_Rad(ReadLog, Option.OutSceneFilename,-1);
- }
-
- /* Close table log */
- if (Option.tablelog == TRUE)
- LogRlog(0,"","");
- }
-